/**
 * 
 */
package com.thor.palmmall.dao.statement;

import java.util.List;

import javax.persistence.Query;

import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.thor.commons.entity.OperateInfo;
import com.thor.commons.jpa.entity.POperateInfo;
import com.thor.commons.query.QueryResult;
import com.thor.commons.query.SQLSubquery;
import com.thor.commons.query2.QueryDefinition2;
import com.thor.commons.query2.QueryDefinitionDecoder2;
import com.thor.commons.query2.QueryExecutor2;
import com.thor.dao.BasicDao;
import com.thor.palmmall.api.statement.AStatementPayBill;
import com.thor.palmmall.dao.statement.converter.PStatementPayBillConverter;
import com.thor.trans.ThorTX;

/**
 * @author liyang
 *
 * @since 1.0
 */
@Transactional(rollbackFor = Exception.class, propagation = Propagation.NOT_SUPPORTED)
public class StatementBillDaoImpl extends BasicDao implements StatementBillDao {

  @Override
  @ThorTX
  public String saveStatementPayBill(PStatementPayBill bill, OperateInfo operateInfo) {
    bill.setLastModifyInfo(POperateInfo.newInstance(operateInfo));
    if (bill.getUuid() == null) {
      bill.setCreateInfo(POperateInfo.newInstance(operateInfo));
      em.persist(bill);
    } else {
      em.merge(bill);
    }
    return bill.getUuid();
  }

  @Override
  public AStatementPayBill getByUuid(String uuid) {
    Query query = em
        .createQuery("from " + PStatementPayBill.class.getName() + " where uuid = :uuid");
    query.setParameter("uuid", uuid);
    List<PStatementPayBill> bills = query.getResultList();
    if (bills.isEmpty())
      return null;
    PStatementPayBill bill = bills.get(0);
    return PStatementPayBillConverter.getInstance().convert(bill);
  }

  @Override
  public QueryResult<AStatementPayBill> query(QueryDefinition2 definition) {
    QueryDefinitionDecoder2 decoder = new QueryDefinitionDecoder2(PStatementPayBill.class, "o");
    decoder.setConditionDecoder(StatementBillQueryDecoder.getInstance());
    decoder.setOrderDecoder(StatementBillQueryDecoder.getInstance());
    
    SQLSubquery sql = decoder.decode(definition);
    sql.addSelect("o");
    QueryResult<PStatementPayBill> queryResult = new QueryExecutor2(em, sql)
        .query(definition.getPageNumber(), definition.getPageSize(), PStatementPayBill.class);
    return queryResult.convert(PStatementPayBillConverter.getInstance());
  }

  @Override
  public AStatementPayBill getByBillNumber(String billNumber) {
    Query query = em.createQuery(
        "from " + PStatementPayBill.class.getName() + " where billNumber = :billNumber");
    query.setParameter("billNumber", billNumber);
    List<PStatementPayBill> bills = query.getResultList();
    if (bills.isEmpty())
      return null;
    PStatementPayBill bill = bills.get(0);
    return PStatementPayBillConverter.getInstance().convert(bill);
  }
}
